#include <BlockingQueue.hh>
#include <Worker.hh>
#include "WorkerTest.hh"

Mutex CAddTask::Key;
Number CAddTask::Sum = 0;

ResultOf WorkerTest::testBasicCase(Worker* Worker)
{
	ResultOf Result;
	CAddTask* NewTask;
	
	for (Number LC = 1; LC <= 10; LC++)
	{
		NewTask = new CAddTask;
		checkNullWR(NewTask, "NewTask is NULL.");
		
		Result = NewTask->setData((void*)LC);
		checkErrorWR(Result, "Fail NewTask->setData.");
		
		Result = Worker->fetchTask(NewTask);
		checkErrorWR(Result, "Fail Worker->fetchTask.");
	}
	
	Result = Worker->work();
	checkErrorWR(Result, "Fail Worker->work.");
	
	Result = Worker->retire();
	checkErrorWR(Result, "Fail Worker->retire.");
	
	if (CAddTask::report() != 55)
	{
		notifyError(CAddTask::report(), "The resulting value is incorrect.");
		return RETURN_ERROR;
	}
	
	return RETURN_OK;
}

ResultOf WorkerTest::testCooperation(Worker* W, Worker* W2, Worker* W3)
{
	Number Sum = 0;
	ResultOf Result;
	CAddTask* NewTask;
	
	Result = W->work();
	checkErrorWR(Result, "Fail Worker->work.");
	
	Result = W2->work();
	checkErrorWR(Result, "Fail Worker->work.");
	
	Result = W3->work();
	checkErrorWR(Result, "Fail Worker->work.");
	
	for (Number LC = 1; LC <= 1000; LC++)
	{
		Sum += LC;
		
		NewTask = new CAddTask;
		checkNullWR(NewTask, "NewTask is NULL.");
		
		Result = NewTask->setData((void*)LC);
		checkErrorWR(Result, "Fail NewTask->setData.");
		
		Result = W->fetchTask(NewTask);
		checkErrorWR(Result, "Fail Worker->fetchTask.");
	}
	
	Result = W->retire();
	checkErrorWR(Result, "Fail Worker->retire.");
	
	Result = W2->retire();
	checkErrorWR(Result, "Fail Worker->retire.");
	
	Result = W3->retire();
	checkErrorWR(Result, "Fail Worker->retire.");
	
	if (CAddTask::report() != Sum)
	{
		notifyError(CAddTask::report(), "The resulting value is incorrect.");
		notifyError(Sum, "Sum");
		return RETURN_ERROR;
	}
	
	return RETURN_OK;
}

ResultOf testWorker()
{
	ResultOf Result;
	WorkerTest Test;
	BlockingQueue MyQueue;
	
	Worker TestWorker(&MyQueue);
	Worker TestWorker2(&MyQueue);
	Worker TestWorker3(&MyQueue);
	
// 	Result = Test.testBasicCase(&Worker);
// 	checkErrorWR(Result, "Fail Test.testBasicCase.");
	
	Result = Test.testCooperation(&TestWorker, &TestWorker2, &TestWorker3);
	checkErrorWR(Result, "Fail Test.testCooperation.");
	
	fprintf(stderr, "Worker: Test success.\n");
	return RETURN_OK;
}
